﻿using System;
using System.Collections.Generic;
using System.Text;

namespace Ex03.GarageManagementSystem.ConsoleUI
{
    public class ConsoleUI
    {
        enum MainMenuOption
        {
            AddNewCar = 1,
            PrintLicenseNumberInTheGarage,
            ChangeVehicleState,
            InfalteWheels,
            RefuelVehicle,
            RechargeVehicle,
            PrintAllDetailsAboutAVehicle,

            exit
        }

        GarageLogic.GarageManagment m_Garage = new GarageLogic.GarageManagment();

        public ConsoleUI()
        {
            Console.WriteLine("Hello And Welcome To Garage Managment{0}", Environment.NewLine);
        }

        public void Run()
        {
            Console.Clear();
            MainMenuOption userSelected = mainMenu();
            Console.Clear();
            switch (userSelected)
            {
                case MainMenuOption.AddNewCar:
                    this.checkVehicleStatus();
                    break;
                case MainMenuOption.PrintLicenseNumberInTheGarage:
                    this.printLicenseNumberInTheGarage();
                    break;
                case MainMenuOption.ChangeVehicleState:
                    this.changeVehicleState();
                    break;
                case MainMenuOption.InfalteWheels:
                    this.infalteWheelsToMax();
                    break;
                case MainMenuOption.RefuelVehicle:
                    this.refuelVehicle();
                    break;
                case MainMenuOption.RechargeVehicle:
                    this.rechargeVehicle();
                    break;
                case MainMenuOption.PrintAllDetailsAboutAVehicle:
                    this.printAllDetailAboutAVehicle();
                    break;
                case MainMenuOption.exit:
                    Environment.Exit(0);
                    break;
                default:
                    break;
            }
            Run();
        }

        private void refuelVehicle()
        {
            String licenseNumber = null;
            String userInput = null;
            GarageLogic.EnergyType.eEnergyType fuelTypeToRefuel = GarageLogic.EnergyType.eEnergyType.DefaultValue;
            float amountOfFuelToRefuel = 0;

            Console.WriteLine("Refule Vehicle ");
            Console.WriteLine("Enter License Number: ");
            licenseNumber = Console.ReadLine();
            if (this.m_Garage.isVehicleInTheGarage(licenseNumber))
            {
                fuelTypeToRefuel = choosefuletype(licenseNumber);
                do
                {
                    Console.Write("Enter Amount Of Fuel to Refuel: ");
                    userInput = Console.ReadLine();
                } while (!float.TryParse(userInput, out amountOfFuelToRefuel));

                try
                {

                    m_Garage.RefuelInternalCombustionVehicle(licenseNumber, fuelTypeToRefuel, amountOfFuelToRefuel);
                    Console.WriteLine("Vehicle Refueled,");
                }
                catch (Exception Ex)
                {
                    Console.WriteLine("{0}", Ex.Message);
                }
            }
            else
            {
                Console.WriteLine("Vehicle With License Number {0} Not Found In The Garage,", licenseNumber);
            }

            Console.WriteLine("Press Enter To Resume..");
            Console.ReadLine();
        }

        private void rechargeVehicle()
        {
            String licenseNumber = null;
            String userInput = null;
            float amountOfMinuteToRecharge = 0;

            Console.WriteLine("Recharge Vehicle ");
            Console.WriteLine("Enter License Number: ");
            licenseNumber = Console.ReadLine();
            if (this.m_Garage.isVehicleInTheGarage(licenseNumber))
            {
                do
                {
                    Console.Write("Enter Amount Of Minutes to Recharge: ");
                    userInput = Console.ReadLine();
                } while (!float.TryParse(userInput, out amountOfMinuteToRecharge));

                try
                {
                    m_Garage.RechargeElectricVehicle(licenseNumber, amountOfMinuteToRecharge);
                    Console.WriteLine("Vehicle Recharged,");
                }
                catch (Exception Ex)
                {
                    Console.WriteLine("{0}", Ex.Message);
                }
            }
            else
            {
                Console.WriteLine("Vehicle With License Number {0} Not Found In The Garage,", licenseNumber);
            }

            Console.WriteLine("Press Enter To Resume..");
            Console.ReadLine();
        }

        private GarageLogic.EnergyType.eEnergyType choosefuletype(String LicenseNumber)
        {
            String[] energyTypes = null;
            String userInput = null;
            GarageLogic.EnergyType.eEnergyType fuelTypeToRefuel = GarageLogic.EnergyType.eEnergyType.DefaultValue;
            bool inputValid = false;

            Console.WriteLine("Choose Fuel Type:");
            energyTypes = Enum.GetNames(typeof(GarageLogic.EnergyType.eEnergyType));
            do
            {
                for (int i = 0; i < energyTypes.Length; i++)
                {
                    Console.WriteLine("{0}. {1}.", i + 1, energyTypes[i]);
                }
                userInput = Console.ReadLine();
                try
                {
                    fuelTypeToRefuel = (GarageLogic.EnergyType.eEnergyType)Enum.Parse(typeof(GarageLogic.EnergyType.eEnergyType), userInput);
                    inputValid = Enum.IsDefined(typeof(MainMenuOption), fuelTypeToRefuel);
                    if (!inputValid)
                    {
                        Console.WriteLine("Error Not In Selection Range");
                    }
                }
                catch
                {
                    inputValid = false;
                }
            } while (!inputValid);

            return fuelTypeToRefuel;
        }

        private void infalteWheelsToMax()
        {
            String licenseNumber = null;

            Console.WriteLine("Inflate Wheels To Max ");
            Console.WriteLine("Enter License Number: ");
            licenseNumber = Console.ReadLine();
            if (this.m_Garage.isVehicleInTheGarage(licenseNumber))
            {
                this.m_Garage.InflateAllVehicleWheelsToMaximumAirPressure(licenseNumber);
                Console.WriteLine("Wheels Inflated To Max Air Pressure");
            }
            else
            {
                Console.WriteLine("Vehicle With License Number {0} Not Found In The Garage,", licenseNumber);
            }

            Console.WriteLine("Press Enter To Resume..");
            Console.ReadLine();
        }

        private void changeVehicleState()
        {
            String userInput = null;
            String licenseNumber = null;
            String[] typeOfRepairState = m_Garage.GetVehicleRepairState();
            bool inputValid = true;

            Console.WriteLine("Changing Vehicle State ");
            Console.WriteLine("Enter License Number: ");
            licenseNumber = Console.ReadLine();
            if (m_Garage.isVehicleInTheGarage(licenseNumber))
            {
                do
                {
                    Console.WriteLine("Change State To:");
                    Console.WriteLine("1. In Repair");
                    Console.WriteLine("2. Repaired");
                    Console.WriteLine("3. Bill Paid");
                    userInput = Console.ReadLine();
                    if (userInput == "1")
                    {
                        m_Garage.ChangeVehicleState(licenseNumber, GarageLogic.GarageManagment.eVehicleRepairState.InRepair);
                        inputValid = true;
                    }
                    else if (userInput == "2")
                    {
                        m_Garage.ChangeVehicleState(licenseNumber, GarageLogic.GarageManagment.eVehicleRepairState.Repaired);
                        inputValid = true;
                    }
                    else if (userInput == "3")
                    {
                        m_Garage.ChangeVehicleState(licenseNumber, GarageLogic.GarageManagment.eVehicleRepairState.BillPaid);
                        inputValid = true;
                    }
                    else
                    {
                        Console.WriteLine("Error with Input Try Again");
                        inputValid = false;
                    }
                } while (!inputValid);
                Console.WriteLine("Vehicle State Changed,");
            }
            else
            {
                Console.WriteLine("Vehicle With License Number {0} Not Found In The Garage,", licenseNumber);
            }

            Console.WriteLine("Press Enter To Resume..");
            Console.ReadLine();
        }

        private void checkVehicleStatus()
        {
            String licenseNumber = null;

            Console.WriteLine("Enter License Number");
            Console.WriteLine("If Exist In The Garage The Vehicle Stats will Change to In Repair State ");
            Console.WriteLine("If Not Exist In The Garage New Vehicle Will Be Insert To the System ");
            Console.Write("The License Number : ");
            licenseNumber = Console.ReadLine();
            if (m_Garage.InsertVehicleToMachineShop(licenseNumber))
            {
                Console.WriteLine("{0}Vehicle Not Found In The Garage, Insterted As New {0}", Environment.NewLine);
                this.addNewVehicle(licenseNumber);
            }
            else
            {
                Console.WriteLine("{0}Vehicle Move To In In Repair Status{0}", Environment.NewLine);
                Console.WriteLine("Press Enter To Resume..");
                Console.ReadLine();
            }
        }

        private void addNewVehicle(String i_LicenseNumber)
        {
            List<String> getQustionsToAskUser;
            List<String> sendAnswersToUpdateVehicle = null;
            bool garageGetAllTheData = false;
            GarageLogic.VehicleTypes.eVehicleType choosenVehicleType = GarageLogic.VehicleTypes.eVehicleType.Electric_Bike;

            Console.Clear();
            Console.WriteLine("Adding New Vehicle");
            Console.WriteLine("==================");
            choosenVehicleType = chooseVehicleType();
            m_Garage.AddNewVehicleToGarage(i_LicenseNumber, choosenVehicleType);
            do
            {
                Console.Clear();
                sendAnswersToUpdateVehicle = new List<String>();
                Console.WriteLine("Vehicle Selected : {0}", choosenVehicleType);
                
                getQustionsToAskUser = m_Garage.UpdateVehicleData(i_LicenseNumber);
                foreach (String Qustion in getQustionsToAskUser)
                {
                    Console.WriteLine("{0}", Qustion);
                    sendAnswersToUpdateVehicle.Add(Console.ReadLine());
                }
                try
                {
                    m_Garage.senddate(sendAnswersToUpdateVehicle, i_LicenseNumber);
                    garageGetAllTheData = true;
                }
                catch (Exception EX)
                {
                    Console.WriteLine(EX.Message);
                    Console.WriteLine("Please Try Again, Press Enter To Resume..");
                    Console.ReadLine();
                }
            } while (!garageGetAllTheData);


            Console.WriteLine("Data Updated, Press Enter To Resume..");
            Console.ReadLine();
        }

        private GarageLogic.VehicleTypes.eVehicleType chooseVehicleType()
        {
            String[] listofVehicleTypes = m_Garage.GetVehicleType();
            GarageLogic.VehicleTypes.eVehicleType choosenVehicleType = GarageLogic.VehicleTypes.eVehicleType.Electric_Bike;
            bool validateInput = false;
            String userInput;

            do
            {
                Console.WriteLine("Choose Vehicle Type: ");
                for (int i = 0; i < listofVehicleTypes.Length; i++)
                {
                    Console.WriteLine("{0}. {1}.", i + 1, listofVehicleTypes[i]);
                }
                userInput = Console.ReadLine();
                try
                {
                    choosenVehicleType = (GarageLogic.VehicleTypes.eVehicleType)Enum.Parse(typeof(GarageLogic.VehicleTypes.eVehicleType), userInput);
                    validateInput = Enum.IsDefined(typeof(GarageLogic.VehicleTypes.eVehicleType), choosenVehicleType);
                    if (!validateInput)
                    {
                        Console.WriteLine("Error Not In Range Of Selection");
                    }
                }
                catch
                {
                    Console.WriteLine("Error please Enter the number before the vehicle type");
                }
            } while (!validateInput);

            return choosenVehicleType;
        }

        private void printLicenseNumberInTheGarage()
        {
            String[] typeOfRepairState = m_Garage.GetVehicleRepairState();
            String userInput = null;
            bool intersectWithDesiredState = true;
            List<String> allLicenseList = null;
            bool inputValid = true;

            do
            {
                inputValid = true;
                Console.WriteLine("1. All License In The Garage");
                Console.WriteLine("2. All License In The Garage With Stats In Repair");
                Console.WriteLine("3. All License In The Garage With Stats Repaired");
                Console.WriteLine("4. All License In The Garage With Stats Bill Paid");

                userInput = Console.ReadLine();


                if (userInput == "1")
                {
                    allLicenseList = m_Garage.GetListOfVehiclesInGarageLicenseNumbers(!intersectWithDesiredState, GarageLogic.GarageManagment.eVehicleRepairState.BillPaid);
                    inputValid = true;
                }
                else if (userInput == "2")
                {
                    allLicenseList = m_Garage.GetListOfVehiclesInGarageLicenseNumbers(intersectWithDesiredState, GarageLogic.GarageManagment.eVehicleRepairState.InRepair);
                    inputValid = true;
                }
                else if (userInput == "3")
                {
                    allLicenseList = m_Garage.GetListOfVehiclesInGarageLicenseNumbers(intersectWithDesiredState, GarageLogic.GarageManagment.eVehicleRepairState.Repaired);
                    inputValid = true;
                }
                else if (userInput == "4")
                {
                    allLicenseList = m_Garage.GetListOfVehiclesInGarageLicenseNumbers(intersectWithDesiredState, GarageLogic.GarageManagment.eVehicleRepairState.BillPaid);
                    inputValid = true;
                }
                else
                {
                    inputValid = false;
                    Console.WriteLine("Error with Input Try Again");
                }
            } while (!inputValid);

            Console.Clear();

            foreach (String license in allLicenseList)
            {
                Console.WriteLine("{0}", license);
            }

            Console.WriteLine("Enter Enter To Resume..");
            Console.ReadLine();
        }

        private void printAllDetailAboutAVehicle()
        {
            List<String> stringToPrint = null;
            String licenseNumber = null;

            Console.WriteLine("Prints All the Details About A Vehicle");
            Console.Write("Enter License Number:");
            licenseNumber = Console.ReadLine();
            if (!m_Garage.isVehicleInTheGarage(licenseNumber))
            {
                Console.WriteLine("Vehicle is not in The Garage");
            }
            else
            {
                stringToPrint = m_Garage.GetAllDataAboutAVehicle(licenseNumber);
                foreach (String Str in stringToPrint)
                {
                    Console.WriteLine("{0}", Str);
                }
            }
            Console.WriteLine("Press Enter To Resume..");
            Console.ReadLine();
        }

        private MainMenuOption mainMenu()
        {
            MainMenuOption returnValue = MainMenuOption.AddNewCar;
            String userInput = null;
            bool validateInput = false;

            Console.WriteLine("What Whould you like to do? ");
            Console.WriteLine("1. Add New Vehicle, or move existing to Repair mode");
            Console.WriteLine("2. Print Licenses In The Garage");
            Console.WriteLine("3. Change Vehicle State");
            Console.WriteLine("4. Infalte Wheels To Maximum");
            Console.WriteLine("5. Refuel Vehicle");
            Console.WriteLine("6. Recharge Vehicle");
            Console.WriteLine("7. Print Details About A Vehicle By Licenses Number");
            Console.WriteLine("8. Exit");
            userInput = Console.ReadLine();
            try
            {
                returnValue = (MainMenuOption)Enum.Parse(typeof(MainMenuOption), userInput);
                validateInput = Enum.IsDefined(typeof(MainMenuOption), returnValue);
                if (!validateInput)
                {
                    Console.Clear();
                    mainMenu();
                }
            }
            catch
            {
                Console.Clear();
                mainMenu();
            }

            return returnValue;
        }

    }
}

